<?php

/**
 * @desc Front structure filter. Control language set and define active resource. 
 *
 */
class Kernel_Filter_Structure extends Kernel_Filter 
{

    /**
     * @desc Active resource ID. 
     *
     * @var integer
     */
    static protected $_id; 
    
    /**
     * @desc Start filter. 
     *
     */
    public function process() 
    {
        // control system language if it's necessary 
        $this->_forward(new Kernel_i18n_Structure(array(
            'callback' => array(&$this, 'location')), Application::getRequest()->lang()
            ));
        
        parent::process();
        
        // search for resource id
        $id = $this->_getActiveElement();
        
        if (empty($id)) {
            $this->_abort('Resource not found');
        }

        // save resource id
        self::$_id = $id;
        $this->_setTemplates();
    }
    
    /**
    * @desc Callback method as only the current strucuture knows how to behaviour 
    * right. 
    * 
    */
    public function location($lang) 
    {
        $this->_location($lang);
    }
    
    /**
     * @desc Return active resource ID. 
     *
     * @return  integer
     */
    static public function getMenuId() 
    {
        return (int)self::$_id;
    }
    
    /**
    * Return resource url by module. Generally used for hidden resources
    * 
    * @param string $module
    * @return string
    */
    static public function getModuleUrl($module, $option) 
    {
        $query = '
            SELECT 
                   `url` 
              FROM 
                   `system_resource` 
             WHERE 
                   `module` = "' . database::escape($module) . '" 
               AND 
                   `option` = ' . (int)$option . '
             LIMIT 
                   1
            ';
        return database::fetchOne($query);
    }
    
    /**
     * @desc Define resource ID matching current url. 
     *
     * @param   array   $params
     * @return  integer
     */
    private function _getActiveElement() 
    {
        $uri = Application::getRequest()->uri();
        
        // in case of empty uri
        if (empty($uri)) {
            
            // try to find resource matching site root
            $id = $this->_findActiveElement('');
            
            // in case of absence
            if (empty($id)) {

                // define uri by default
                if (strlen($uri = $this->_getDefaultUrl()) > 0) {
                    
                    // do not forget to place language if needed 
                    $lang_needed = Application::getRequest()->isMultilang()
                        ? Application::getRequest()->lang() . '/'
                        : '';
                    // redirect agent setting URL obviously to avoid multi 
                    // URLs to the same page
                    $this->_location($lang_needed . $uri, true);
                }
            }
            return $id;
        } else {
            for ($size = count($uri); $size > 0; $size--) {
                $slice = implode('/', array_slice($uri, 0, $size));
                if (($id = $this->_findActiveElement($slice)) > 0) {
                    return $id;
                }
            }
        }

        return false;
    }

    /**
     * @desc Search for resource ID matching cthe current URL. 
     *
     * @param   string  $url
     * @return  integer
     */
    protected function _findActiveElement($url) 
    {
        $query = 'SELECT
                         `id`
                    FROM
                         `system_resource`
                   WHERE
                         `url` = "' . database::escape($url) . '"';
        return database::fetchOne($query);
    }

    /**
     * @desc Return dafault resource ID - it's ID the first main menu item links 
     * on. 
     *
     * @return  string
     */
    protected function _getDefaultUrl() 
    {
        $query = 'SELECT
                         `r`.`url`
                    FROM
                         `system_navigation` `n`
              INNER JOIN
                         `system_navigation_item` `i`
                      ON
                         `i`.`menu_id` = `n`.`id`
                     AND
                         `i`.`parent_id` = 0
              INNER JOIN
                         `system_resource` `r`
                      ON
                         `r`.`id` = `i`.`resource_id`
                ORDER BY
                         -- основное меню навигации
                         `n`.`id`,

                         -- первый пункт меню
                         `i`.`position`
                   LIMIT
                         1';

        return database::fetchOne($query);
    }
    
    protected function _setTemplates() 
    {
        $query = '
            SHOW 
                 FIELDS 
            FROM 
                 `system_resource` 
            LIKE 
                  "%_template"
            ';
        if (count(database::fetchAll($query))) {
            $query = '
                SELECT 
                       `frame_template`, 
                       `inner_template` 
                  FROM 
                       `system_resource` 
                 WHERE 
                       `id` = ' . (int)self::$_id;
            list($frame, $template) = array_values(database::fetchRow($query));
            
            $response = Application::getResponse();
            if (strlen($template) > 0) {
                $response->setTemplate($template);
            }
            if (strlen($frame) > 0) {
                $response->setFrameTemplate($frame);
            }
        }
    }
    
}
